using DA.AnimGraph;
using OdinSerializer;
using System.Collections.Generic;
using System.Linq;

namespace DA.AnimGraph.Editor {

    internal class AGANode_Sequence : AGANode_SampleBase, IResourceNode {

        public override AGANodeModelBase modelProperty { set => model = (AGANodeModel_Sequence)value; get => model; }
        [OdinSerialize] AGANodeModel_Sequence model;

        public AGANode_Sequence(AGANodeModelBase model) : base(model) {
        }

        public override int Publish(List<PublishNode> outNodes, AGAPublisher.PublishContext context) {
            var pNode = new SequencePNode();
            pNode.uuid = uuid;
            pNode.data = model.Publish(context);
            var index = outNodes.Count;
            outNodes.Add(pNode);
            PublishPerks(pNode, context);
            return index;
        }

        public AUID[] GetResources() {
            return model.GetResources();
        }
        public void ReplaceResourceAUID(Dictionary<AUID, AUID> uuidMapping) {
            model.ReplaceResourceAUID(uuidMapping);
        }
    }


    [ModelOf(typeof(AGANode_Sequence))]
    internal class AGANodeModel_Sequence : AGANodeModelBase {

        public List<AGAFieldModel_SequenceClipSlice> clipSlices = new();
        public AGAFieldModel_FloatLink playbackSpeed = new() { defaultValue = 1 };
        public bool isAutoConnect;

        public SequenceNode.SetupData Publish(AGAPublisher.PublishContext context) {
            if (!isAutoConnect) {
                AGAFieldModel_SequenceClipSlice.Sort(clipSlices);
            }
            var clipsDesc = new ClipLinkDesc[clipSlices.Count];
            var clipSliceDesc = new SequenceNode.ClipSlice[clipSlices.Count];
            for (int i = 0; i < clipSlices.Count; i++) {
                clipsDesc[i] = clipSlices[i].clip.Publish(context);
                clipSliceDesc[i] = new SequenceNode.ClipSlice() {
                    offset = clipSlices[i].offset,
                    start = clipSlices[i].start,
                    end = clipSlices[i].start + clipSlices[i].length,
                };
            }
            return new SequenceNode.SetupData() {
                clipsDesc = clipsDesc,
                clipSlices = isAutoConnect ? null : clipSliceDesc,
                playbackSpeedDesc = playbackSpeed.Publish(context),
            };
        }

        internal AUID[] GetResources() {
            return clipSlices.Select(x => x.clip.clipKey).Where(x => x.isValid).ToArray();
        }
        public void ReplaceResourceAUID(Dictionary<AUID, AUID> uuidMapping) {
            foreach (var p in clipSlices) {
                if (uuidMapping.TryGetValue(p.clip.clipKey, out var newId)) {
                    p.clip.clipKey = newId;
                }
            }
        }
    }

}